#include "widget.h"
#define menubarHeight 40
#define leftedge 40
Widget::Widget(QMainWindow *parent) :
    QMainWindow(parent)
{   //设置窗口信息，标题和图标
    this->setWindowFlags(this->windowFlags()& ~Qt::WindowMaximizeButtonHint);
    this->setWindowTitle("万能摄像头上位机@Avengers出品");
    this->setWindowIcon(QIcon(":/point/Point/Avengers.jpg"));
    openStatus = false;//未打开文件
    this->resize(1050,570+menubarHeight);
    setFixedSize(this->width(), this->height());
    this->move(0,0);
    //读入黑白块
    blackPoint = new QPixmap;
    blackPoint->load(":/point/Point/BlackPoint.png");
    *blackPoint = blackPoint->scaled(7,7);
    whitePoint = new QPixmap;
    whitePoint->load(":/point/Point/WhitePoint.png");
    *whitePoint = whitePoint->scaled(7,7);
    redPoint = new QPixmap;
    redPoint->load(":/point/Point/RedPoint.png");
    pointArray[0] = *blackPoint;
    pointArray[1] = *whitePoint;
    //图像区域的定义
    //imgLabel显示图像用的label
    mapGroup = new QGroupBox(this);
    mapGroup->move(0,menubarHeight);
    mapGroup->setTitle("图像显示区");
    mapLayout = new QGridLayout(this);
    mapGroup->setLayout(mapLayout);
    //imgLabel.setParent(this);
    mapLayout->addWidget(&imgLabel,0,0,1,1);
    mapGroup->resize(600,500);

    //imgLabel.move(0+leftedge,0+menubarHeight);
    imgLabel.resize(560,420);

    //mapimg显示的图像
    mapImg.load(":/point/Point/BlackPoint.png");
    mapImg = mapImg.scaled(Width,Height);
    //载入到label
    imgLabel.setPixmap(QPixmap::fromImage(mapImg).scaled(560,420));
    //存储所有图像
    for (int i=0;i<maxScreen;i++)
        mapPix[i] = new QPixmap;
    //初始化图像中的两条横线


    lineLabelx = new QLabel(this);
    lineLabelx->setPixmap(redPoint->scaled(560,7));
    lineLabelx->resize(560,7);

    lineLabely = new QLabel(this);
    lineLabely->setPixmap(redPoint->scaled(7,420));
    lineLabely->resize(7,420);

    lineLabelx->move(19,92);
    lineLabely->move(19,92);
    lineLabelx->setVisible(false);
    lineLabely->setVisible(false);

    //打开文件
    sourceFile = new QFile();
    //显示文件名
    openMode = -1;//未指定打开模式
    //显示按钮

    CurrentImage = 0; //当前是第几幅图片,0~Sum 。
    //加载数据

    //位置控制，数字型
    setPosition = new QSpinBox(this);
    setPosition->move(15+leftedge,500+menubarHeight);
    setPosition->resize(90,30);
    setPosition->setRange(0,maxScreen);
    //connect(setPosition,SIGNAL(valueChanged(int)),this,SLOT(JumpTo()));
    //跳图
    Jump = new QPushButton(this);
    //Jump->setVisible(false);
    Jump->resize(40,30);
    Jump->setText("跳转");
    Jump->move(10,500+menubarHeight);
    connect(Jump,SIGNAL(clicked(bool)),this,SLOT(JumpTo()));
    //图片总数
    sumLabel = new QLabel(this);
    sumLabel->setText("总数：0");
    sumLabel->resize(150,30);
    sumLabel->move(50,530+menubarHeight);
    setSpeed = new QSpinBox(this);
    setSpeed->setValue(60);
    setSpeed->move(450,500+menubarHeight);
    setSpeed->resize(40,30);
    //帧率显示
    speedLabel = new QLabel(this);
    speedLabel->move(490,500+menubarHeight);
    speedLabel->resize(30,30);
    speedLabel->setText("fps");
    //按帧率播放视频
    Play = new QPushButton(this);
    Play->setText("播放");
    Play->move(520,500+menubarHeight);
    Play->resize(40,30);
    connect(Play,SIGNAL(clicked(bool)),this,SLOT(playStart()));
    //滚动条
    scrollPosition = new QScrollBar(this);
    scrollPosition->move(150,500+menubarHeight);
    scrollPosition->resize(300,30);
    scrollPosition->setOrientation(Qt::Horizontal);
    scrollPosition->setMaximum(0);
    scrollPosition->setMinimum(0);
    connect(scrollPosition,SIGNAL(valueChanged(int)),this,SLOT(toScroll(int)));
    //零散数据的表格
    dataGroup = new QGroupBox("变量显示区",this);
    dataGroup->move(625,menubarHeight);
    dataGroup->resize(400,300);
    dataLayout = new QGridLayout();
    QFont font0("宋体",10,1);
    QFont font1("宋体",10,1);
    for (int i=0;i<8;i++)
        for (int j=0;j<4;j++)
        {
            dataLabel[i][j] = new QLabel(this);
            if (j==0||j==2)
            {
                dataLabel[i][j]->setAlignment(Qt::AlignCenter);
                dataLabel[i][j]->setFont(font0);
            }
            else
            {
                dataLabel[i][j]->setAlignment(Qt::AlignCenter);
                dataLabel[i][j]->setFont(font1);
            }
            dataLayout->addWidget(dataLabel[i][j],i,j,1,1);
            dataLabel[i][j]->setText(QString::number(i)+","+QString::number(j));
        }
    for (int i=0;i<5;i++)
        varName[i] = "预留"+QString::number(i);
    setDataName();
    dataGroup->setLayout(dataLayout);
    //位变量显示窗口
    for (int i=0;i<8;i++)
        bitName[i] = "位"+QString::number(i);
    bitGroup = new QGroupBox("位变量显示区",this);
    bitGroup->move(625,300+menubarHeight);
    bitGroup->setFixedSize(400,100);
    bitLayout = new QGridLayout();
    bitGroup->setLayout(bitLayout);
    for (int i=0;i<8;i++)
    {
        bitLabel[i] = new QLabel(this);
        bitLabel[i]->setText(bitName[i]);
        bitLayout->addWidget(bitLabel[i],0,7-i,1,1);
    }
    for (int i=0;i<8;i++)
    {
        bitDataLabel[i] = new QLabel(this);
        bitDataLabel[i]->setText(QString::number(i));
        bitLayout->addWidget(bitDataLabel[i],1,7-i,1,1);
    }

    //设置窗口
    settingButton = new QPushButton(this);
    settingButton->setText("设置...");
    settingButton->setVisible(false);
    settingButton->resize(80,20);
    settingButton->move(920,630+menubarHeight);
    connect(settingButton,SIGNAL(clicked(bool)),this,SLOT(setting()));
    //颜色预置
    lAv = qRgb(0,255,0);
    rAv = qRgb(0,0,255);
    lIav = qRgb(255,255,0);
    rIav = qRgb(255,0,0);
    mAv = qRgb(255,153,51);
    //在线模式
    onlineModeStatus = false;

    //PWM窗口
    pwmButton = new QPushButton(this);
    pwmButton->setText("显示PWM窗口");
    pwmButton->setVisible(false);
    pwmButton->resize(150,30);
    pwmButton->move(850,600+menubarHeight);
    connect(pwmButton,SIGNAL(clicked(bool)),this,SLOT(showPWM()));
    pwmShow_init();
    defaultFile = new QPushButton(this);
    defaultFile->resize(100,20);
    defaultFile->move(0,600+menubarHeight);
    defaultFile->setText("打开默认文件");
    connect(defaultFile,SIGNAL(clicked(bool)),this,SLOT(openDefaultFile()));
    defaultFile->setVisible(false);
    loadDefaultSetting();
    //十字弯标识
    isCross = new int[maxScreen];
    carStatus = new unsigned  char[maxScreen];
    crossLabel = new QLabel(this);
    QFont font10("宋体",10);
    crossLabel->setFont(font10);
    crossLabel->setText("十字弯");
    crossLabel->move(575,450+menubarHeight);
    crossLabel->resize(50,20);
    //crossLabel->setVisible(false);
    statusLabel = new QLabel(this);
    statusLabel->setFont(font10);
    statusLabel->setText("普通路径");
    statusLabel->move(625,450+menubarHeight);
    statusLabel->resize(50,20);
    //statusLabel->setVisible(false);
    //数据表
    dataSheetWidget  = new QWidget();

    datasheet = new DataSheet();
    dataframe = new QFrame(dataSheetWidget);
    datalayout = new QGridLayout();
    datalayout->addWidget(datasheet,1,1,1,1);
    dataframe->setLayout(datalayout);
    dataframe->setFixedSize(800,QApplication::desktop()->height()-200);


    dataSheetWidget->setLayout(datalayout);
    dataframe->setVisible(false);
    dataSheetWidget->resize(800
                           ,QApplication::desktop()->height()-200);
    dataframe->move(0,0);
    //状态显示区
    processGroup = new QGroupBox(this);
    processGroup->setTitle("图像分析显示区");
    processLayout = new QGridLayout(this);
    processGroup->setLayout(processLayout);
    processGroup->move(625,400+menubarHeight);
    processGroup->resize(400,100);

    processLabel[0] = new QLabel(this);
    QFont processLabelTitleFont(processLabel[0]->font().family(),10);
    processLayout->addWidget(processLabel[0],0,0,1,1);
    processLabel[0]->setFont(processLabelTitleFont);
    processLabel[0]->setText("赛道状态");
    processLabel[0]->setAlignment(Qt::AlignCenter);

    processLabel[1] = new QLabel(this);
    processLayout->addWidget(processLabel[1],0,1,1,1);
    processLabel[1]->setText("车辆状态");
    processLabel[1]->setAlignment(Qt::AlignCenter);
    processLabel[1]->setFont(processLabelTitleFont);

    deltaLabel1 = new QLabel(this);
    deltaLabel1->setText("偏差1");
    deltaLabel1->setAlignment(Qt::AlignCenter);
    deltaLabel1->setFont(processLabelTitleFont);
    processLayout->addWidget(deltaLabel1,0,2,1,1);

    deltaLabel2 = new QLabel(this);
    deltaLabel2->setText("偏差2");
    deltaLabel2->setAlignment(Qt::AlignCenter);
    deltaLabel2->setFont(processLabelTitleFont);
    processLayout->addWidget(deltaLabel2,0,3,1,1);

    deltaDataLabel1 = new QLabel(this);
    deltaDataLabel1->setText("0");
    deltaDataLabel1->setAlignment(Qt::AlignCenter);
    processLayout->addWidget(deltaDataLabel1,1,2,1,1);

    deltaDataLabel2 = new QLabel(this);
    deltaDataLabel2->setText("0");
    deltaDataLabel2->setAlignment(Qt::AlignCenter);
    processLayout->addWidget(deltaDataLabel2,1,3,1,1);

    processLayout->addWidget(crossLabel,1,0,1,1);
    crossLabel->setAlignment(Qt::AlignCenter);
    processLayout->addWidget(statusLabel,1,1,1,1);
    statusLabel->setAlignment(Qt::AlignCenter);
    //添加菜单栏
    setMenuBar();
    //鼠标位置
    QFont mouseFont("宋体",12);
        mousePos = new QLabel(this);
        mousePos->move(200,570);
        mousePos->resize(230,40);
        mousePos->setFont(mouseFont);
        mousePos->setText("x = 0,y = 0");
    this->setFocus();

}
void Widget::setDataName()//数据表格的命名
{
    using namespace std;
    const string str[8][4] = {
                            {"斜率","0","中段偏差","0"},
                            {"左斜率","0","右斜率","0"},
                            {"斜率P输出","0","中段偏差P输出","0"},
                            {"斜率D输出","0","中段偏差D输出","0"},
                            {"舵机总输出","0","总有效行数","0"},
                            {"左有效行","0","右有效行","0"},
                            {"左冲出保护斜率","0","右冲出保护斜率","0"},
                            {"左冲出行补偿","0","右冲出行补偿","0"}
                            //{"","","",""}
                         };
    for (int i=0;i<8;i++)
        for (int j=0;j<4;j++)
        {
            dataLabel[i][j]->setText(QString::fromStdString(str[i][j]));
        }

}
void Widget::setBitDataName()
{
    for (int i=0;i<8;i++)
        bitLabel[i]->setText(bitName[i]);
}

bool Widget::mapData[500][500] = {0};//临时使用的数据表格
int Widget::mainData[16][maxScreen] = {{0}};
unsigned char Widget::bitData[maxScreen] = {0};

Widget::~Widget()
{
}
void Widget::openFile(void)//打开文件
{
    fileName = QFileDialog::getOpenFileName();
    if (fileName=="")
    {
        QMessageBox::information(this,"注意","没有打开任何文档。\n将保持上个文档的打开状态。","确定");
        return;
    }
    delete sourceFile;
    sourceFile = new QFile(fileName);

}
void Widget::openDefaultFile()
{
    fileName = QCoreApplication::applicationDirPath()+"/defaultfile.bin";
    sourceFile = new QFile(fileName);
    if (!sourceFile->exists())
        return;
    openMode = 1;
    loadFile();
}
void Widget::loadDefaultSetting()
{
    settingDialog = new SettingDialog();
    settingDialog->loadFileName = QCoreApplication::applicationDirPath()+"/settings.ini";
    QFile tFile(settingDialog->loadFileName);
    if (!tFile.exists())
        return;

    settingDialog->loadDefault();
    changeSettings();
    delete settingDialog;
}
void Widget::loadFile()  //装载文件
{
    CurrentImage = 0;
    QFile * F = sourceFile;
    if (F->fileName()=="")
    {
        QMessageBox::warning(this,"空文件","请先选择一个文件!","确定");
        return;
    }
    if (openMode==-1)
        return;
    if (QMessageBox::warning(this,"提示","是否转换格式？",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
        toSave = 1;
    else
        toSave = 0;

    F->open(QFile::ReadOnly);
    char ch;
    F->read(&ch,1);
    Sum = -1;
    datasheet->setScale(Width,Height);


    if (openMode == 0)
    //0是边缘图，1是位图
    while (1)
    {
       if (F->atEnd())
           break;
       if ((unsigned char)ch==0xf0)
       {
           F->read(&ch,1);
           if ((unsigned char)ch==0x0f)
           {
               Sum++;
               loadScreen(Sum,F);
           }
       }
       else
           F->read(&ch,1);
    }
    if (openMode == 1)
    {
        while (1)
        {
           if (F->atEnd())
               break;
           if ((unsigned char)ch==0xf0)
           {
                   Sum++;
                   loadScreen(Sum,F);
           }
           F->read(&ch,1);
           if (F->atEnd()&&(unsigned char)ch!=0x0f)
               Sum--;
        }
    }
    //openMode == 2 时为主路图
    if (openMode==2)
    {
            while (1)
            {
               if (F->atEnd())
                   break;
               if ((unsigned char)ch==0xf0)
               {
                       Sum++;
                       loadScreen(Sum,F);
               }
               F->read(&ch,1);
               if (F->atEnd()&&(unsigned char)ch!=0x0f)
                   Sum--;
            }
    }

    if (openMode==3)
    {
        while (1)
        {
           if (F->atEnd())
               break;
           if ((unsigned char)ch==0xf0)
           {
                   Sum++;
                   loadScreen(Sum,F);
           }
           F->read(&ch,1);
           if (F->atEnd()&&(unsigned char)ch!=0x0f)
               Sum--;
        }
    }
    F->close();


    if (Sum==-1)
    {
        QMessageBox::warning(this,"文件不合法","无法读取文件，请确认文件格式！","确定");
        return;
    }
    else
        openStatus = true;
    scrollPosition->setMaximum(Sum+1);
    scrollPosition->setMinimum(1);
    sumLabel->setText("总数："+QString::number(Sum+1));
    //pwmshow->setSum(Sum);
    showMap();
}
/*数据的解析函数在此*/
void Widget::loadScreen(int n, QFile *F)  //加载某一场的数据
{
    char ch,lastch;
    //先按原来的数据读着

    if (openMode == 1)//边沿
    {
        int leftEdge[Height+1][11] = {0};
        int rightEdge[Height+1][11] = {0};
        //60*10个左边沿 把边缘图读入到mapdata中
        for (int i=1;i<=Height;i++)
            for (int j=1;j<=countChanges;j++)
            {
                F->read(&ch,1);
                leftEdge[i][j] = (unsigned char)ch;
            }
        //右边沿
        for (int i=1;i<=Height;i++)
            for (int j=1;j<=countChanges;j++)
            {
                F->read(&ch,1);
                rightEdge[i][j] = (unsigned char)ch;
            }
        //绘图
        for (int i=0;i<Width;i++)
            for (int j=0;j<Height;j++)
                mapData[i][j] = 0;
        for (int i=1;i<=Height;i++)
            for (int j=1;j<=countChanges;j++)
            {
                if (leftEdge[i][j]==0||rightEdge[i][j]==0)
                    break;
                for (int k = leftEdge[i][j]-1;k<=rightEdge[i][j]-1;k++)
                    mapData[k][i-1]=1;
            }
        mapImg = mapImg.scaled(Width,Height);
        QRgb rgb[2] = {qRgb(0,0,0),qRgb(255,255,255)};
        for (int i=0;i<Width;i++)
            for (int j=0;j<Height;j++)
               mapImg.setPixel(i,j,rgb[mapData[i][j]]);
        //左有效

        for (int i=0;i<Height;i++)
        {
            F->read(&ch,1);
            datasheet->setDataItem(2*i,10,n,(unsigned char)ch);
            if (ch!=0)
                mapImg.setPixel((unsigned char)ch-1,i,lAv);
        }
        //右有效
        for (int i=0;i<Height;i++)
        {
            F->read(&ch,1);
            datasheet->setDataItem(2*i,11,n,(unsigned char)ch);
            if (ch!=0)
                mapImg.setPixel((unsigned char)ch-1,i,rAv);
        }
        //中线
        for (int i=0;i<Height;i++)
        {
            F->read(&ch,1);
            datasheet->setDataItem(2*i,12,n,(unsigned char)ch);
            if (ch!=0)
                mapImg.setPixel((unsigned char)ch-1,i,mAv);
        }

        F->read(&ch,1);
        isCross[n] = (unsigned char)ch;//图像状态
        F->read(&ch,1);
        carStatus[n] = (unsigned char)ch;//车状态


        //添加左右边界
        for (int i=1;i<=Height;i++)
            for (int j=1;j<=10;j++)
                datasheet->setDataItem(2*(i-1),j-1,n,leftEdge[i][j]);
        for (int i=1;i<=Height;i++)
            for (int j=1;j<=10;j++)
                datasheet->setDataItem(2*i-1,j-1,n,rightEdge[i][j]);
        F->read(&ch,1);
        while ((unsigned char)ch!=0x0F)
        {
            lastch = ch;
            F->read(&ch,1);
        }
        //lastch 是标志位
        bitData[n] = lastch;//保存标志位


        *mapPix[n] = QPixmap::fromImage(mapImg).scaled(Width,Height);
    }

    if (openMode==2)
    {
        //只读主路
        int leftEdge[Height+1][2] = {0};
        int rightEdge[Height+1][2] = {0};

        for (int i=1;i<=Height;i++)
            for (int j=1;j<=1;j++)
            {
                F->read(&ch,1);
                leftEdge[i][j] = (unsigned char)ch;
            }
        for (int i=1;i<=Height;i++)
            for (int j=1;j<=1;j++)
            {
                F->read(&ch,1);
                rightEdge[i][j] = (unsigned char)ch;
            }

        for (int i=1;i<=Height;i++)
        {
            if (leftEdge[i][1]==0&&rightEdge[i][1]!=0)
                leftEdge[i][1] = 1;
            if (rightEdge[i][1]==0&&leftEdge[i][1]!=0)
                rightEdge[i][1] = Width;
        }
        for (int i=2;i<=Height;i++)
            if (leftEdge[i-1][1]!=0&&rightEdge[i-1][1]!=0)
                if (leftEdge[i][1]==0&&rightEdge[i][1]==0)
                {
                    leftEdge[i][1] = 1;
                    rightEdge[i][1] = Width;
                }


        //绘图
        for (int i=0;i<Width;i++)
            for (int j=0;j<Height;j++)
                mapData[i][j] = 0;
        for (int i=1;i<=Height;i++)
            for (int j=1;j<=1;j++)
            {
                for (int k = leftEdge[i][j]-1;k<=rightEdge[i][j]-1;k++)
                    mapData[k][i-1]=1;
            }
        mapImg = mapImg.scaled(Width,Height);
        QRgb rgb[2] = {qRgb(0,0,0),qRgb(255,255,255)};
        for (int i=0;i<Width;i++)
            for (int j=0;j<Height;j++)
               mapImg.setPixel(i,j,rgb[mapData[i][j]]);


        for (int i=0;i<9;i++)
            loadControlDataSigned16(mainData[i],n,F);
        loadControlDataUnsigned8(mainData[10],n,F);
        loadControlDataUnsigned8(mainData[11],n,F);
        loadControlDataSigned16(mainData[12],n,F);
        loadControlDataSigned16(mainData[13],n,F);
        loadControlDataSigned16(mainData[14],n,F);
        loadControlDataSigned16(mainData[15],n,F);
        loadControlDataUnsigned8(mainData[9],n,F);

        //读入图像类型标记
        F->read(&ch,1);
        isCross[n] = (unsigned char)ch;//图像状态
        F->read(&ch,1);
        carStatus[n] = (unsigned char)ch;//车状态


        *mapPix[n] = QPixmap::fromImage(mapImg).scaled(Width,Height);

    }

    if (openMode==3)
    {
        //读压缩图
        for (int i=0;i<Height;i++)
            for (int j=0;j<Width/8;j++)
            {
                F->read(&ch,1);
                for (int p = 7;p>=0;p--)
                {
                    mapData[j*8+p][i] = ch&0x01;
                    ch = ch>>1;
                }
            }
        //600
        //绘图

        mapImg = mapImg.scaled(Width,Height);
        QRgb rgb[2] = {qRgb(255,255,255),qRgb(0,0,0)};
        for (int i=0;i<Width;i++)
            for (int j=0;j<Height;j++)
               mapImg.setPixel(i,j,rgb[mapData[i][j]]);
        if (toSave)
        {
            QPixmap SavePix;
            QFileInfo finfo(fileName);
            SavePix = QPixmap::fromImage(mapImg,Qt::MonoOnly);
            if (n==0)
            {
                QDir d;
                d.mkdir(finfo.absolutePath()+"\\Convert"+finfo.fileName());
            }
            SavePix.save(finfo.absolutePath()+"\\Convert"+finfo.fileName()+"\\"+QString::number(n)+".bmp",0);
        }
        //左有效
        //660
        for (int i=0;i<Height;i++)
        {
            F->read(&ch,1);
            datasheet->setDataItem(2*i,10,n,(unsigned char)ch);
            if (ch!=0)
                mapImg.setPixel((unsigned char)ch-1,i,lAv);
        }
        //右有效
        //720
        for (int i=0;i<Height;i++)
        {
            F->read(&ch,1);
            datasheet->setDataItem(2*i,11,n,(unsigned char)ch);
            if (ch!=0)
                mapImg.setPixel((unsigned char)ch-1,i,rAv);
        }

        //读入图像类型标记
        F->read(&ch,1);
        isCross[n] = (unsigned char)ch;//图像状态
        F->read(&ch,1);
        carStatus[n] = (unsigned char)ch;//车状态
        F->read(&ch,1);
        bitData[n] = (unsigned char)ch;//标志位
        loadControlDataUnsigned16(mainData[0],n,F);
        for (int i=1;i<9;i++)
            loadControlDataSigned16(mainData[i],n,F);
        loadControlDataUnsigned8(mainData[10],n,F);
        loadControlDataUnsigned8(mainData[11],n,F);
        loadControlDataSigned16(mainData[12],n,F);
        loadControlDataSigned16(mainData[13],n,F);
        loadControlDataUnsigned16(mainData[14],n,F);
        loadControlDataUnsigned16(mainData[15],n,F);
        loadControlDataUnsigned8(mainData[9],n,F);


        *mapPix[n] = QPixmap::fromImage(mapImg).scaled(Width,Height);

    }
    if (openMode == 0)
    {
        //把位图的数据读入到mapdata中
        for (int i=0;i<Height;i++)
            for (int j=0;j<Width/8;j++)
            {
                F->read(&ch,1);
                for (int k=0;k<8;k++)
                {
                    Widget::mapData[j*8+(7-k)][i]=ch&0x01;
                    ch = ch>>1;
                }
            }    
        //生成原始图像的qpixmap
        QRgb rgb[2] = {qRgb(0,0,0),qRgb(255,255,255)};
        for (int i=0;i<Width;i++)
            for (int j=0;j<Height;j++)
               mapImg.setPixel(i,j,rgb[mapData[i][j]]);

        for (int i=Height-1;i>=0;i--)
        {
            F->read(&ch,1);
            mapImg.setPixel((unsigned char)ch,i,lAv);
        }
        for (int i=Height-1;i>=0;i--)
        {
            F->read(&ch,1);
            mapImg.setPixel((unsigned char)ch,i,rAv);
        }
        int tPWM = 0;
        F->read(&ch,1);
        tPWM = ch;
        F->read(&ch,1);
        tPWM+=ch*256;//写数据，先写低八位，再写高八位。读数据，先读低八位，再读高八位。

        F->read(&ch,1);
        tPWM = ch;
        F->read(&ch,1);
        tPWM+=ch*256;
        *mapPix[n] = QPixmap::fromImage(mapImg).scaled(Width,Height);//这句话一定要放在最后。
    }
}
void Widget::showMap() //显示当前的图像
{
    lineLabelx->setVisible(false);
    lineLabely->setVisible(false);
    if (!openStatus)
    {
        QMessageBox::warning(this,"无文件","请先选择文件","确定");
        return;
    }
    setPosition->setValue(CurrentImage+1);
    if (Height/(float)Width==0.75)
        imgLabel.setPixmap(mapPix[CurrentImage]->scaled(560,420));
    else
    {
        imgLabel.setPixmap(mapPix[CurrentImage]->scaled(560,420));
        //为了让图像好看一些改变图像的位置，还没写完。
    }
    //pwmshow->setBasePos(CurrentImage);
   // pwmshow->repaint();
    //设定图像状态和车状态
    if (isCross[CurrentImage]>=0&&isCross[CurrentImage]<=crossCount-1)
        crossLabel->setText(crossText[isCross[CurrentImage]]);
    if (carStatus[CurrentImage]>=0&&carStatus[CurrentImage]<=statusCount-1)
        statusLabel->setText(statusText[carStatus[CurrentImage]]);

    datasheet->showDataItem(CurrentImage);
    for (int i=0;i<8;i++)
        for (int j=0;j<2;j++)
            dataLabel[i][2*j+1]->setText(QString::number(mainData[2*i+j][CurrentImage]));
    //位变量
    for (int i=0;i<=7;i++)
    {
        if ((bitData[CurrentImage]>>i)&0x01)
         bitDataLabel[i]->setText("是");
        else
         bitDataLabel[i]->setText("否");
    }
}
void Widget::timerEvent(QTimerEvent *Event)  //定时器，处理动画播放
{
    showNext();
}
void Widget::showNext() // 显示下一幅图像
{

    if (!openStatus)
    {
        QMessageBox::warning(this,"无文件","请先装载数据","确定");
        return;
    }
        CurrentImage++;
        CurrentImage = CurrentImage%(Sum+1);
        scrollPosition->setValue(CurrentImage+1);
        showMap();
}
void Widget::playStart()  //开始播放
{
    if (!openStatus)
    {
        QMessageBox::warning(this,"无文件","请先装载数据","确定");
        return;
    }
    int t = setSpeed->value();
    if (t==0||t>100)
    {
        QMessageBox::warning(this,"错误","帧率过小或过大","返回");
        return;
    }
    timer_ID = startTimer(1000/t);
    Play->setText("暂停");
    disconnect(Play,SIGNAL(clicked(bool)),this,SLOT(playStart()));
    connect(Play,SIGNAL(clicked(bool)),this,SLOT(playEnd()));
}
void Widget::playEnd()  //停止播放
{
    if (!openStatus)
    {
        QMessageBox::warning(this,"无文件","请先装载数据","确定");
        return;
    }
    killTimer(timer_ID);
    Play->setText("播放");
    disconnect(Play,SIGNAL(clicked(bool)),this,SLOT(playEnd()));
    connect(Play,SIGNAL(clicked(bool)),this,SLOT(playStart()));
    datasheet->showDataItem(CurrentImage);
}
void Widget::JumpTo()//跳到数字指定位置
{
    if (!openStatus)
    {
        QMessageBox::warning(this,"无文件","请先装载数据","确定");
        return;
    }
    int t = setPosition->value();
    if (t<=0||t>Sum+1)
    {
        QMessageBox::information(this,"错误","超出数据范围","确认");
        return;
    }
    CurrentImage = t-1;
    //scrollPosition->setValue(CurrentImage);
    scrollPosition->setValue(CurrentImage+1);
    showMap();
}
void Widget::toScroll(int t)//跳到滚动条指定位置
{
    if (!openStatus)
    {
        QMessageBox::warning(this,"无文件","请先装载数据","确定");
        return;
    }
    CurrentImage = t-1;
    setPosition->setValue(t);
    showMap();
}
void Widget::setting()//打开设置窗口
{

    settingDialog = new SettingDialog();

    connect(settingDialog,SIGNAL(shouldChange()),this,SLOT(changeSettings()));
    settingDialog->rgb_lav = lAv;
    settingDialog->rgb_rav = rAv;
    settingDialog->rgb_liav = lIav;
    settingDialog->rgb_riav = rIav;
    settingDialog->setcolor();
    for (int i=0;i<5;i++)
        settingDialog->setCurrentName(i,varName[i]);
    for (int i=0;i<8;i++)
        settingDialog->setCurrentBitName(i,bitName[i]);
    settingDialog->setCurrentSize(Width,Height);

    settingDialog->exec();
    this->repaint();
    if (openStatus)
        loadFile();
    delete settingDialog;
}
void Widget::changeSettings()//更改设置内容
{

    lAv = settingDialog->rgb_lav;
    rAv = settingDialog->rgb_rav;
    lIav = settingDialog->rgb_liav;
    rIav = settingDialog->rgb_riav;
    for (int i=0;i<5;i++)
        varName[i] = settingDialog->getCurrentName(i);
    for (int i=0;i<8;i++)
        bitName[i] = settingDialog->getCurrentBitName(i);
    switch(settingDialog->getCurrentSize())
    {
    case 0:
        Width = 160;
        Height = 120;
        break;
    case 1:
        Width = 80;
        Height = 60;
        break;
    }
    setDataName();
    setBitDataName();
    this->repaint();
}
void Widget::showPWM()//显示pwm动画
{
    pwmshow->showtry();
}
void Widget::pwmShow_init()//初始化pwm显示
{
    return;
    pwmshow = new PWM_Show(this);
    //pwmshow->initShower(leftPWM,rightPWM,-1);
}
void Widget::enterOnlineMode()
{
    Uarter = new uartProcessor(0,this);
    Uarter->setMapSize(Width,Height);
    openStatus = true;
    Uarter->setTargetColor(&lAv,&rAv,&lIav,&rIav,&mAv);
    Uarter->setTargetPoints(blackPoint,whitePoint);
    Uarter->setTargetData(mapPix[0],datasheet,onlineData);
    CurrentImage = 0;
    connect(Uarter,SIGNAL(done()),this,SLOT(showOnlineMap()));


    //openButton->setEnabled(false);
    disableButtons();
    if (Uarter->Status==0)
    {
        motorTool->setEnabled(false);
        onlineModeMenu->setText("退出在线模式");
        disconnect(onlineModeMenu,SIGNAL(triggered(bool)),this,SLOT(enterOnlineMode()));
        connect(onlineModeMenu,SIGNAL(triggered(bool)),this,SLOT(exitOnlineMode()));
    }
    else
        exitOnlineMode();
}
void Widget::exitOnlineMode()
{
    openStatus = false;
    delete Uarter;

    //openButton->setEnabled(true);
    enableButtons();
    onlineModeMenu->setText("进入在线模式");
    motorTool->setEnabled(true);
    disconnect(onlineModeMenu,SIGNAL(triggered(bool)),this,SLOT(exitOnlineMode()));
    connect(onlineModeMenu,SIGNAL(triggered(bool)),this,SLOT(enterOnlineMode()));
    onlineModeStatus = false;
}
void Widget::showOnlineMap()
{
    imgLabel.setPixmap(mapPix[0]->scaled(560,420));
    //在这儿写 控制量
    //onlineData[1]为
    if (onlineData[1]>=0&&onlineData[1]<=crossCount-1)
        crossLabel->setText(crossText[onlineData[1]]);
    if (onlineData[2]>=0&&onlineData[2]<=statusCount-1)
        statusLabel->setText(statusText[onlineData[2]]);
}
void Widget::enableButtons()
{
    settingButton->setEnabled(true);
    pwmButton->setEnabled(true);
    Jump->setEnabled(true);
    Play->setEnabled(true);
}
void Widget::disableButtons()
{
    settingButton->setEnabled(false);
    pwmButton->setEnabled(false);
    Jump->setEnabled(false);
    Play->setEnabled(false);
}
void Widget::setMenuBar()
{
    fileMenu = this->menuBar()->addMenu("文件(&F)");
    toolMenu = this->menuBar()->addMenu("工具(&T)");
    systemMenu = this->menuBar()->addMenu("系统(&S)");

    motorTool = new QAction("在线电机监视器(...)");
    toolMenu->addAction(motorTool);
    connect(motorTool,SIGNAL(triggered(bool)),this,SLOT(showMotorTool()));

    QAction *openEdgeFileMenu = new QAction("打开边沿文件(...)");
    fileMenu->addAction(openEdgeFileMenu);
    connect(openEdgeFileMenu,SIGNAL(triggered(bool)),this,SLOT(openEdgeFile()));

    QAction *openBitFileMenu = new QAction("打开位图文件(...)");
    fileMenu->addAction(openBitFileMenu);
    connect(openBitFileMenu,SIGNAL(triggered(bool)),this,SLOT(openBitFile()));

    QAction *openMainRoad = new QAction("打开主路文件(...)\t");
    fileMenu->addAction(openMainRoad);
    connect(openMainRoad,SIGNAL(triggered(bool)),this,SLOT(openMainRoadFile()));

    QAction *openZipRoad = new QAction("打开压缩文件(...)\t");
    fileMenu->addAction(openZipRoad);
    connect(openZipRoad,SIGNAL(triggered(bool)),this,SLOT(openZipFile()));

    onlineModeMenu = new QAction("进入在线模式");
    toolMenu->addAction(onlineModeMenu);
    connect(onlineModeMenu,SIGNAL(triggered(bool)),this,SLOT(enterOnlineMode()));

    QAction *pwmMenu = new QAction("显示PWM窗口(...)");
    pwmMenu->setEnabled(false);
    toolMenu->addAction(pwmMenu);
    connect(pwmMenu,SIGNAL(triggered(bool)),this,SLOT(showPWM()));

    QAction * tableMenu = new QAction("显示数据表格");
    toolMenu->addAction(tableMenu);
    connect(tableMenu,SIGNAL(triggered(bool)),dataSheetWidget,SLOT(show()));

    QAction *settingMenu = new QAction("设置(...)\t");
    systemMenu->addAction(settingMenu);
    connect(settingMenu,SIGNAL(triggered(bool)),this,SLOT(setting()));

    QAction *useCustomSize = new QAction("使用自定义图像(...)\t");
    systemMenu->addAction(useCustomSize);
    connect(useCustomSize,SIGNAL(triggered(bool)),this,SLOT(showCustomSize()));

    systemMenu->addSeparator();

    QAction *aboutMenu = new QAction("关于此软件\t");
    systemMenu->addAction(aboutMenu);

    connect(aboutMenu,SIGNAL(triggered(bool)),this,SLOT(showAboutInfo()));

    QAction *helpMenu = new QAction("帮助信息");
    systemMenu->addAction(helpMenu);
}
void Widget::showMotorTool()
{
    motorShow = new MotorShow(this);
    if (motorShow->getStatus()==1)
        motorShow->exec();
    delete motorShow;
}
void Widget::openEdgeFile()
{
    openMode = 1;
    openFile();
    if (sourceFile->fileName()!="")
        loadFile();
}
void Widget::openZipFile()
{
    openMode = 3;
    openFile();
    if (sourceFile->fileName()!="")
        loadFile();
}

void Widget::openBitFile()
{
    openMode = 0;
    openFile();
    if (sourceFile->fileName()!="")
        loadFile();
}
void Widget::showAboutInfo()
{
    QMessageBox::information(this,"关于此软件","制作者：牛凯程@Avengers\n山东大学智能车实验室\n","返回");
}
void Widget::showCustomSize()
{
    CustomSize *customSize = new CustomSize(this);
    customSize->exec();
    customSize->move(this->x()+300,this->y()+300);
    if (customSize->changed)
    {
        Width = customSize->newWidth;
        Height = customSize->newHeight;
    }
    delete customSize;
}
void Widget::mousePressEvent(QMouseEvent *Event)
{

    this->setFocus();

    int tx = Event->x()-19;
    int ty = Event->y()-92;
    if ((tx/7+1)>80||(ty/7+1)>60||tx<0||ty<0)
        return;
    lineLabelx->setVisible(true);
    lineLabely->setVisible(true);
    if (Height==120)
    mousePos->setText("x = "+QString::number((int)(Event->x()/3.5)+1)+
                      ",y = "+QString::number((int)((Event->y()-menubarHeight)/3.5)+1));
    if(Height==60)
        mousePos->setText("x = "+QString::number((int)(tx/7)+1)+
                          ",y = "+QString::number((int)((ty)/7)+1));

    lineLabelx->move(19,(ty/7)*7+92);
    lineLabely->move((tx/7)*7+19,92);

}
void Widget::mouseMoveEvent(QMouseEvent *event)
{

    this->setFocus();
    int tx = event->x()-19;
    int ty = event->y()-92;
    if ((tx/7+1)>80||(ty/7+1)>60||tx<0||ty<0)
        return;
    if (Height==120)
    mousePos->setText("x = "+QString::number((int)(event->x()/3.5)+1)+
                      ",y = "+QString::number((int)((event->y()-menubarHeight)/3.5)+1));
    if (Height==60)
        mousePos->setText("x = "+QString::number((int)(tx/7)+1)+
                          ",y = "+QString::number((int)((ty)/7)+1));
    lineLabelx->move(19,(ty/7)*7+92);
    lineLabely->move((tx/7)*7+19,92);

}
void Widget::openMainRoadFile()
{
    openMode = 2;
    openFile();
    loadFile();
}
void Widget::loadControlDataSigned16(int* out,int n,QFile *tF)
{
    char tch[2];
    tF->read(tch,2);
    unsigned char ch[2];
    for (int i=0;i<2;i++)
        ch[i] = (unsigned char)tch[i];
    out[n] =
            (unsigned char)ch[0]*0x00000100+
            (unsigned char)ch[1]*0x00000001
            ;
    if (out[n]>0x00001000)
    {
        ch[0] = ~(ch[0]);
        ch[1] = ~(ch[1]);
        ch[1]++;
        out[n] = -(
                   ch[0]*0x00000100+
                   ch[1]*0x00000001);
    }
}
void Widget::loadControlDataUnsigned16(int *out, int n, QFile *tF)
{
    char tch[2];
    tF->read(tch,2);
    unsigned char ch[2];
    for (int i=0;i<2;i++)
        ch[i] = (unsigned char)tch[i];
    out[n] =
            (unsigned char)ch[0]*0x00000100+
            (unsigned char)ch[1]*0x00000001
            ;
}
void Widget::loadControlDataUnsigned8(int *out, int n, QFile *tF)
{
    char tch[1];
    tF->read(tch,1);
    unsigned char ch[1];
    for (int i=0;i<1;i++)
        ch[i] = (unsigned char)tch[i];
    out[n] =
            (unsigned char)ch[0]*0x00000001
            ;
}
void Widget::keyPressEvent(QKeyEvent *event)
{
    if (!openStatus)
        return;

    switch(event->key())
    {
    case Qt::Key_Return:
    case Qt::Key_Enter:
        JumpTo();
        break;
    case Qt::Key_Space:
        if (Play->text()=="播放")
        {
            setSpeed->setValue(60);
            playStart();
            break;
        }
        if(Play->text()=="暂停")
        {
            playEnd();
            break;
        }
        break;
    case Qt::Key_Left:
        CurrentImage--;
        if (CurrentImage<0)
            CurrentImage = 0;
        showMap();
        break;
    case Qt::Key_Right:
        CurrentImage++;
        if (CurrentImage>=Sum)
            CurrentImage = Sum-1;
        showMap();
        break;
    default:
        break;
    }
}
